package Game 
{
	import Engine.Engine;
	import Engine.utils.Stats;
	import flash.desktop.NotificationType;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	/**
	 * ...
	 * @author Vijay Ramani
	 */
	public class MainGame extends Sprite 
	{
		public 	static const SECTOR_SIZE:uint = 800;
		private static const STARFIELD_RATIO:Number = 0.5;
		private static const STARFIELD_DENSITY:Number = 0.1;
		private static const MIN_STARSIZE:Number = 1;
		private static const MAX_STARSIZE:Number = 3;
		private static const MIN_STAR_BRIGHTNESS:Number = 0.5;
		private static const PELLETS_PER_SECTOR:uint = 10;
		
		private var mainRef:Main = null;
		private var starField:GameEntity = null;
		private var universe:Sprite = null;
		private var camera:GameCamera = null;
		private var gameObjs:Array = new Array();
		private var gameGridSize:uint = 3;
		private var universeBounds:Rectangle = new Rectangle();
		private var ship:Ship = null;
		
		
		// Game Debug Objects
		private static var debugLayer:Sprite = null;
		private static var debugObjects:Array =  new Array();
		
		private static function AddDebugLayer(_ref:Sprite):void
		{
			debugLayer = new Sprite();
			_ref.addChild(debugLayer);
		}
		private static function DrawDebugLayer(_offset:Point = null):void
		{
			debugLayer.graphics.clear();
			var _offX:Number = 0;
			var _offY:Number = 0;
			if (_offset)
			{
				_offX = _offset.x;
				_offY = _offset.y;
			}
			//for (var i:uint = 0;i<
		}
		
		
		public static function DebugAddLine(_p1:Point, _p2:Point, _c:uint = 0xFF0000):Object
		{
			var _obj:Object = { t:0, p1:_p1, p2:_p2, c:_c };
			debugObjects.push(_obj);
			return _obj;
		}
		
		public static function RemoveDebugObject(_o:Object):void
		{
			var _ind:int = debugObjects.indexOf(_o);
			debugObjects.splice(_ind, 1);
		}
		
		public function MainGame() 
		{
			mainRef = Main.GetRef();
			Init();
		}
		
		public function Init():void
		{
			Sector.InitSectors(gameGridSize);
			InitUniverse(gameGridSize);
			universeBounds.x = 0;
			universeBounds.y = 0;
			universeBounds.width = SECTOR_SIZE * gameGridSize;
			universeBounds.height = SECTOR_SIZE*gameGridSize;
			//*
			// Debug Sectors
			var _secGridOverlay:GameEntity = new GameEntity();
			Sector.DrawSectorGrid(_secGridOverlay.graphics);
			_secGridOverlay.Pos.x = _secGridOverlay.Pos.y = 0;
			AddGameEntity(_secGridOverlay);
			
			AddDebugLayer(this);
			
			/**/
			var _fd:Stats = new Stats();
			_fd.x = mainRef.StageWidth - 60;
			_fd.y = 0;
			addChild(_fd);
			
		}
		private function InitUniverse(_size:uint):void
		{
			
			camera = new GameCamera(new Rectangle(0, 0, mainRef.StageWidth, mainRef.StageHeight));
			
			starField = new GameEntity();
			starField.addChild(GenerateStarField(_size * SECTOR_SIZE));
			starField.Pos.x = starField.Pos.y = 0;
			AddGameEntity(starField, STARFIELD_RATIO);
			
			// Add Energy Pellets to each Sector
			var _p:EnergyPellet = null
			for (var i:uint = 0; i < gameGridSize; i++)
			{
				for (var j:uint = 0; j < gameGridSize; j++)
				{
					for (var k:uint = 0; k < PELLETS_PER_SECTOR; k++)
					{
						_p = new EnergyPellet();
						_p.Pos.x = _p.width / 2 + Math.random() * (SECTOR_SIZE - _p.width);
						_p.Pos.y = _p.height / 2 + Math.random() * (SECTOR_SIZE - _p.height);
						
						_p.Pos.x += i * SECTOR_SIZE;
						_p.Pos.y += j * SECTOR_SIZE;
						
						AddGameEntity(_p);
					}
				}
			}
			
			ship = new AiShip();
			ship.Pos.x = SECTOR_SIZE / 2;
			ship.Pos.y = SECTOR_SIZE / 2;
			
			AddGameEntity(ship);
			
			// For Debug only
			ship.Pos.x = 200;
			ship.Pos.y = 200;
		}
		
		private function GenerateStarField(_size:uint):Sprite
		{
			var _stars:Sprite = new Sprite();
			
			_stars.graphics.lineStyle(4, 0xFF0000);
			_stars.graphics.drawRect(0, 0, _size, _size);
			
			_stars.graphics.lineStyle();
			var _numStars:uint = _size * STARFIELD_DENSITY;
			var _starSize:uint = 1;
			for (var i:uint = 0; i < _numStars; i++ )
			{
				_starSize = MIN_STARSIZE + (MAX_STARSIZE - MIN_STARSIZE) * Math.random();
				_stars.graphics.beginFill(0xFFFFFF,MIN_STAR_BRIGHTNESS+(1-MIN_STAR_BRIGHTNESS)*Math.random());
				_stars.graphics.drawRect(_size* Math.random(), _size* Math.random(), _starSize, _starSize);
				_stars.graphics.endFill();
			}
			
			return _stars;
		}
		
		public function Update():void
		{	
			if (mainRef.KeyRight && camera.Pos.x < 3 * SECTOR_SIZE - mainRef.StageWidth)
			{
				camera.Pos.x += 10;
			}
			else if (mainRef.KeyLeft && camera.Pos.x > 0)
			{
				camera.Pos.x -= 10;
			}
			else if (mainRef.KeyUp && camera.Pos.y > 0)
			{
				camera.Pos.y -= 10;
			}
			else if (mainRef.KeyDown && camera.Pos.y < 3 * SECTOR_SIZE - mainRef.StageHeight)
			{
				camera.Pos.y += 10;
			}
			
			ship.Update();
			
			//trace("Update: " + mainRef.KeyDown);
			
			if (mainRef.MouseDown)
			{
			//	camera.MoveTo(mainRef.MouseX, mainRef.MouseY);
			}
			
			camera.Update();
			
			if (debugLayer) DrawDebugLayer(camera.Pos);
		}
		
		public function AddGameEntity(_obj:GameEntity, _depth:Number = 1):GameEntity
		{
			if (_obj == null) throw("Null Game Entity Added");
			gameObjs.push(_obj);
			if(_obj.Type > 0) Sector.AddToSectors(_obj);
			camera.AddToRenderList(_obj, _depth);
			addChild(_obj);
			_obj.WorldRef = this;
			
			return _obj;
		}
		public function RemoveGameEntity(_obj:GameEntity):void
		{
			if (_obj == null) return;
			
			if (_obj.Type > 0) _obj.SectorRef.Remove(_obj);
			var _ind:int = gameObjs.indexOf(_obj);
			if (_ind < 0) return;
			gameObjs.splice(_ind, 1);
			removeChild(_obj);
		}
		public function get Bounds():Rectangle
		{
			return universeBounds;
		}
	}
}







